package com.baizhi.aop;

import com.baizhi.annotation.LogAnnotation;
import com.baizhi.dao.BzLogMapper;
import com.baizhi.entity.BzAdmin;
import com.baizhi.entity.BzLog;
import com.baizhi.enums.LogTypeEnum;
import com.baizhi.util.IPKit;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Configuration
public class LogAop {
    @Autowired
    private BzLogMapper logMapper;
    @Autowired
    private HttpServletRequest request;

    @Around("@annotation(com.baizhi.annotation.LogAnnotation)")
    public Object logAround(ProceedingJoinPoint joinPoint){
        /**
         * 1.获取日志数据
         */
        BzLog bzLog = new BzLog();

//        日期
        bzLog.setLogDate(new Date());

//        ip 通过工具类
        String ipAddrByRequest = IPKit.getIpAddrByRequest(request);
        bzLog.setLogIp(ipAddrByRequest);

//        session 用户名
        BzAdmin admin = (BzAdmin) request.getSession().getAttribute("admin");

        if (admin != null) {
            bzLog.setUsername(admin.getUsername());
        }else {
            bzLog.setUsername("hhh");
        }

        /**
         * 操作内容和类型
         * 难点：调用的方法不同 所需要获取到的类型和内容是不同的
         * 自定义注解（定义 类型和内容）
         * 通过切面获取自定义注解中的数据
         *
         * 获取目标方法上的注解 连接点对象
         */
//        1.获取方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        2.通过方法签名对象获取方法对象
        Method method = signature.getMethod();
//        3.通过方法对象获取方法上的注解
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);

        LogTypeEnum type = annotation.type();

//        获取枚举的变量名
        bzLog.setLogType(type.name());
        bzLog.setLogContent(annotation.content());


//        获取方法名
        bzLog.setLogMethod(method.toString());

//        执行时间
        long startTime = System.currentTimeMillis();
        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        long endTime = System.currentTimeMillis();

        bzLog.setLogTime(endTime-startTime);
        /**
         * 2.日志信息添加数据库
         */
        System.out.println(bzLog);
        logMapper.insert(bzLog);


        return result;
    }
}
